﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace CMTVision.Widgets.Framework
{
    public class BaseTemplateContainer: System.Web.UI.UserControl, CMTVision.Widgets.Framework.ITemplateContainer
    {
        #region Ctor

        public BaseTemplateContainer()
            :base()
        {
            IsInEditMode = false;
        }

        #endregion

        #region Implements ITemplatePage interface

        /// <summary>
        /// Get or Set the template container id.
        /// Would better be initialized before base.OnInit.
        /// </summary>
        public long TemplateContainerID
        {
            get;
            set;
        }

        public bool IsInEditMode
        {
            get;
            set;
        }

        /// <summary>
        /// Get the Template holder which is used for loading the template
        /// (Show be implemented by derived class)
        /// </summary>
        public virtual System.Web.UI.Control TemplateHolder
        {
            get
            {
                throw new InvalidOperationException("Need to override the property:'TemplateHolder'!");
            }
        }

        public virtual CMTVision.Widgets.Framework.ITemplate LoadWidgetStoreTemplate()
        {
            if (TemplateContainerID > 0)
            {
                Model.TemplateContainer templateContainer = null; 
                using (CMTVision.Model.CMTWidgetsEntities entity = CMTVision.Common.EntitiesManager.LoadWidgetEntity())
                {                    
                    templateContainer = (from tp in entity.TemplateContainers.Include("Template.TemplateType") where tp.ID == TemplateContainerID
                                                                &&tp.Template!=null 
                                                                &&tp.Template.TemplateType!=null 
                                                            select tp).FirstOrDefault();                   
                }
                if (templateContainer != null && templateContainer.Template != null && templateContainer.Template.TemplateType != null)
                {
                    CMTVision.Widgets.Framework.ITemplate template = Page.LoadControl(templateContainer.Template.TemplateType.Src) as CMTVision.Widgets.Framework.ITemplate;
                    (template as System.Web.UI.Control).ID = Util.GenerateID<ITemplate>(templateContainer.Template.ID.ToString());
                    template.TemplateContainerID = TemplateContainerID;
                    template.TemplateID = templateContainer.Template.ID;
                    template.IsInEditMode = IsInEditMode;
                    template.LoadTemplateColumns();
                    return template;
                }
            }
            return null;
        }
        
        public virtual void Refresh()
        {
            if (Template != null)
            {
                Template.Refresh();
            }
        }

        #endregion
         

        protected override void OnInit(EventArgs e)
        {
            base.OnInit(e);
            EnsureWidgetsTemplate();
        }
         
        /// <summary>
        /// Ensure the widgets template has been loaded and added into the template holder.
        /// If you want to reload the template during other time dynamically, you could invoke this method
        /// to reload the template. But view state may be lost if not invoked in OnInit.
        /// </summary>
        public void EnsureWidgetsTemplate()
        {
            if (TemplateHolder != null)
            {
                TemplateHolder.Controls.Clear();
                Template = LoadWidgetStoreTemplate();
                if (Template != null)
                {
                    var templateControl = Template as System.Web.UI.Control;
                    if (templateControl != null)
                    { 
                        TemplateHolder.Controls.Add(templateControl);
                    }
                }
            }
        }
         
        /// <summary>
        /// Get the Template loaded in the Container
        /// </summary>
        public ITemplate Template
        { get; protected set; }

       
        #region Relative Class Name to initialize Drag&Drop

        public string SortableColumnClassName
        {
            get;
            set;
        }

        public string DraggableWidgetContainerClassName
        {
            get;
            set;
        }

        public string LockWidgetContainerClassName
        {
            get;
            set;
        }

        public string SortableHandlerClassName
        {
            get;
            set;
        }

        public string SortablePlaceHolderClassName
        {
            get;
            set;
        }

        public string TemplatePostBackTriggerClassName
        {
            get;
            set;
        }

        /// <summary>
        /// Get or Set new widget class name
        /// which is used to indicate that we could drag the element to the column
        /// to add a new widget into the column
        /// </summary>
        public string NewWidgetClassName
        {
            get;
            set;
        }

        public string NewWidgetTitleClassName
        {
            get;
            set;
        }

        #endregion

        #region Registe the Drag&Drop initialize script

        /// <summary>
        /// Get or Set the control which is used to registe the Drag Drop initialization JavaScript,
        /// If you wrap the columns with updatepanel, you should better assign it with the updatepanel, 
        /// or other server controls in the updatepanel. 
        /// </summary>
        public virtual System.Web.UI.Control RegisterScriptOn
        {
            get { return this; }
        }

        /// <summary>
        /// Prepare work to registe initializing drag and drop. 
        /// Maybe we could set the relative class name through override this method
        /// </summary>
        protected virtual void PreparingInitDragDrop()
        {
        }

        protected override void OnPreRender(EventArgs e)
        {
            PreparingInitDragDrop();
            System.Web.UI.ScriptManager.RegisterStartupScript(RegisterScriptOn,
                                                              RegisterScriptOn.GetType(),
                                                              this.ClientID + "_InitDragDrop",
                                                              Util.GenerateDragDropInitializeScript(SortableColumnClassName,
                                                                                                    DraggableWidgetContainerClassName,
                                                                                                    LockWidgetContainerClassName,
                                                                                                    SortableHandlerClassName,
                                                                                                    SortablePlaceHolderClassName,
                                                                                                    TemplatePostBackTriggerClassName,
                                                                                                    NewWidgetClassName,
                                                                                                    NewWidgetTitleClassName
                                                                                                    ),
                                                              true);
            base.OnPreRender(e);
        }

        #endregion

    }
}
